package com.jielihaofeng.nettyadvance.rpc.client.handler;

import com.jielihaofeng.nettyadvance.rpc.message.RpcResponseMessage;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.util.concurrent.Promise;
import lombok.extern.slf4j.Slf4j;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * @author Johnnie Wind
 * @description RPC响应消息处理器
 * @date 2021/11/19 14:44
 */
@Slf4j
@ChannelHandler.Sharable
// 虽然用了共享变量，但是我们考虑了线程安全对象，是可以用Sharable的
public class RpcResponseMessageHandler extends SimpleChannelInboundHandler<RpcResponseMessage> {

    // 序号 用来接收结果的 promise 对象
    public static final Map<Integer, Promise<Object>> PROMISES = new ConcurrentHashMap<>();

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, RpcResponseMessage msg) {

        // 拿到空的 promise，并且从集合中移除，避免越来越大
        Promise<Object> promise = PROMISES.remove(msg.getSequenceId());
        if (promise != null) {
            // 调用结果
            Object returnValue = msg.getReturnValue();
            // 调用异常
            Exception exceptionValue = msg.getExceptionValue();
            // 打印结果
            if (exceptionValue == null) {
                promise.setSuccess(returnValue);
                log.info("RPC调用成功，返回结果：{}", returnValue);
            } else {
                promise.setFailure(exceptionValue);
                log.error("RPC调用失败，返回异常。", exceptionValue);
            }
        }


    }
}
